home *** CD-ROM | disk | FTP | other *** search
- /*
- xthing
- ------
- A little set of routines that allow you to stuff
- tasks in the time manager queue, which will be fed back to you
- in the XThingList queue, accessed within the application's
- main loop by calling ProcessXThingTask.
-
- 7:17:22 PM 10/28/92
- By Brigham Stevens
- Apple Computer, Inc.
- Developer Technical Support
-
-
- At init time call InitXThingTimer.
- Call StartXThing to add a task and start its clock.
- Call AddXThing to only add a task and NOT start its clock.
- At the end of your program call KillAllXThingTasks
- If your task wants to remove itself, it should return false.
-
- Xthing tasks have the form of:
-
- Boolean XThingUpdateTask(xthing *xtp, long dataRef)
- {
- myDataStruct *mdp;
- Boolean result;
-
- mdp = (myDataStruct *)dataRef;
-
- mdp.count++; // do something usefull (less)
-
- if(mdp.count)
- result = true; // want to be run again
- else
- result = false; // tell Xthing not to re-install us
- }
-
- See Sprite.c for more examples.
-
- */
-
- #include "xthing.h"
- #include "ZAMProtos.h"
-
- static void XThingTimeTask(void);
-
- static long xThingCount = 0;
- static xQHdr XThingList;
-
- void InitXThingTimer(void)
- {
- xInitQueueHeader(&XThingList);
- }
-
- static void XThingTimeTask(void)
- {
- /* Time manager points to time task record in a1 */
- /* We have all our data located after that, so it */
- /* is simple to just do our thing */
-
- asm {
- st.b xthing.taskFlag(a1)
- }
- }
-
- void ProcessXThingTask(short numTasksToProcess)
- /*
- Whip through the queue until there
- are no more entires. Each item is
- ripped from the queue, it's associated task
- is called, and the item is then fed back to
- the Time Manager task, which will give it back to us here
- when it is done chewing on it.
-
- If the user interface slows down because of too many things going on,
- you might want to add a task that basically calls your event loop
- once in a while. Then you could make this the main loop of your
- program if you were so inclined.
- */
- {
- xthing *xtp;
- updateProc updateJSR;
- Boolean reTime;
- OSErr err;
-
- for(xtp = (xthing*)XThingList.qHead; xtp != nil; xtp = xtp->next) {
- if(xtp->taskFlag) {
- xtp->taskFlag = false;
- updateJSR = (updateProc)xtp->actionProc;
- if(updateJSR) {
- reTime = (*updateJSR)(xtp,xtp->dataRef);
- if(reTime) {
- RmvTime(&xtp->timer);
- InsTime(&xtp->timer);
- PrimeTime(&xtp->timer, xtp->interval);
- }
- }
- }
- }
- }
-
-
- void EnqueueXThing(xthing *xtp)
- {
-
- xThingCount++;
-
- if(xtp->inList == false) { // change to bit field in taskFlag later
- xEnqueue(xtp,&XThingList);
- xtp->inList = true;
- }
- }
-
- void AddXThing(xthing *xtp, long prime, updateProc updtProc, long dataRef)
- /*
- This adds a thing to the xthing list, but does not start the tasks
- */
- {
- short err = noErr;
-
- if(err == noErr) {
- /* set up default values */
-
- xtp->timer.tmAddr = (ProcPtr)XThingTimeTask;
-
- xtp->interval = prime;
- xtp->taskFlag = false;
- xtp->dataRef = dataRef;
- xtp->actionProc = updtProc;
- xtp->waiting = true;
-
- EnqueueXThing(xtp);
- }
-
- }
-
-
- xthing *StartXThing(xthing *xtp, long prime, updateProc updtProc, long dataRef)
- /*
- The best thing about this
- is that it takes almost NO parameters
- pass the timing interval in prime
- a pointer to the update routine in updtProc
- and an application-defined reference in refcon.
- */
- {
- short err = noErr;
-
- /* allocate a new thing */
- if(xtp == nil) {
- xtp = (xthing*)NewPtrClear(sizeof(xthing));
- if(!xtp){
- err = MemError();
- ErrMsgCode("\pNewPtrClear failed in StartThing",err);
- }
- }
-
- if(err == noErr) {
- /* set up default values */
-
- xtp->timer.tmAddr = (ProcPtr)XThingTimeTask;
-
- xtp->interval = prime;
- xtp->taskFlag = false;
- xtp->dataRef = dataRef;
- xtp->actionProc = updtProc;
- xtp->waiting = true;
-
- EnqueueXThing(xtp);
-
- InsTime((QElemPtr)&xtp->timer);
- PrimeTime(&xtp->timer, xtp->interval);
- }
-
- return xtp;
- }
-
-
- void KillAllXThingTasks(void)
- {
- xthing *xtp;
-
- for(xtp = (xthing*)XThingList.qHead; xtp != nil; xtp = xtp->next) {
- if( (xtp->timer.qType & TaskActiveFlag) != 0)
- RmvTime(&xtp->timer);
- }
- }
-